/*
 * RunTests.cpp
 *
 *  Created on: Apr 15, 2012
 *      Author: desilva
 */

#include <cstdio>           //printf
#include <iostream>         //cout, cerr
#include <string>
#include <iomanip>
#include "TranscriptFactory.h"
#include "TranscriptParser.h"
#include "UMReportsData.h"

using namespace std;

//Declarations
void displayTranscript(TranscriptParser* student);

//Definitions
/**
 * This main function will test (and demo) the functionality of the mock
 * database code.
 */
int main()
{
    cout << "Starting parser test..." << endl << endl;
    //    string filePath = "../testData/transcript.xml";

    std::vector<TranscriptFactory::StudentInfo> studentList =
            TranscriptFactory::getStudentList();

    if(studentList.size() == 0)
    {
        cout << "NO STUDENTS TO VIEW" << endl;
        return 0;
    }
    //else -- we can view a student

    for(unsigned int k = 0; k < studentList.size(); k++)
    {
        cout << "Student " << k << "..." << endl;
        TranscriptParser* student =
                TranscriptFactory::getInstance(studentList[k].studentId);

        //Make sure the student Ids match (so the getInstance function generally
        //  works).
        if(studentList[k].studentId != student->getStudentId())
        {
            cerr << "Names did not match.  The Factory gave us the wrong student!"
                    << endl;
            return 1;
        }

        try
        {
            displayTranscript(student);
        }
        catch (int errorNum)
        {
            cerr << endl << "Performing Cleanup..." << endl;
            delete student;

            return errorNum;
        }

        cerr << endl << "Performing Cleanup..." << endl;
        delete student;
    }
    cerr << endl << "Ending parser test..." << endl;
    return 0;
}

/**
 * Display the details from the student's transcript.
 * @param student  the student to display the information for.
 * @throw errorNum  this value is 2 if the name is improperly formatted.
 */
void displayTranscript(TranscriptParser* student)
{
    vector<string> nameVector;
    student->getStudentName(&nameVector);
    if(nameVector.size() < 2)
    {
        cerr << "Student name not long enough!" << endl;
        throw 2;
    }

    //Format the student's name
    string name = nameVector[nameVector.size() - 1] + ",";
    for (unsigned int j = 0; j < nameVector.size() - 1; j++)
    {
        name.append(" ");
        name.append(nameVector[j]);
    }
    cout << left;
	cout<<"=================Student Transcript==============="<<endl;
	cout<<"++++++++++++++++++++Basic Info++++++++++++++++++++"<<endl;
	cout<<setw(12)<<"Name: "<<name<<endl
	        <<setw(12)<<"ID:    "<<student->getStudentId()<<endl
	        <<setw(12)<< "Advisor: " << student->getDegreeAdvisor() << endl
	        <<setw(12)<< "Program:  " << student->getDegreeProgram() << endl
	        <<setw(12)<< "Plan: " << student->getDegreePlan() << endl
	        <<setw(12)<< "Degree:   " << student->getDegreeName() << endl << endl;

	//Print out the course list
	cout << "++++++++++++++++++++Course List++++++++++++++++++++ " << endl;

    vector<Course> courseList;
    student->getCourses(&courseList);
    for (unsigned int i = 0; i < courseList.size(); i++)
    {
        Course course = courseList[i];
        printf("%4s %4s  %2s  (%d)  %6s %4s  %d %02.3f\n",
               course.subject.c_str(),
               course.course.c_str(),
               course.grade.c_str(),
               course.crdAttempted,
               course.term.c_str(),
               course.year.c_str(),
               course.crdEarned,
               course.gradePoints);
    }

    //Now, get the stuff from the "other DBs"
    cout << "  Extended Information" << endl;

    cout << "    Degree Admission Date:  " << student->getDegreeAdmissionDate()
            << endl;

    //Okay, so I know that I probably shouldn't use both cout and printf, but
    //  c'est la vie.
    pair<string, string> degreeStart = student->getDegreeStartSemester();
    printf("    Degree Start Semester:  %s %s\n",
           degreeStart.first.c_str(),
           degreeStart.second.c_str());

    //Display the committee members
    cout << "    Committee Members:" << endl;
    vector<string> committee = student->getCommitteMembers();

    UMReportsData reportInfo = UMReportsData();
    for (unsigned int k = 0; k < committee.size(); k++)
    {
        cout << "      " << committee[k] << "  (" << boolalpha
                << reportInfo.isProfessorInternal(committee[k]) << ")" << endl;
    }

    //Degree Program Form Info.
    pair<TranscriptParser::DegreeProgramFormStatus, string>
            degreePgmFormStatus = student->getDegreeProgramFormStatus();
    cout << "    Degree Program Form Status: " << degreePgmFormStatus.first
            << "  (" << degreePgmFormStatus.second << ")" << endl;

    cout << "    Plan: " << student->getPlanInfo() << endl;
}
